#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
typedef double db;
inline int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar(); }
	while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+ch-'0'; ch=getchar(); }
	return x*f;
}
const int MAXN=1e5+10;
int n,m,a[MAXN],b[MAXN],sub[MAXN],cnt,head[MAXN];
struct edge
{
	int v,next;
}e[MAXN*2];
void addedge(int x,int y)
{
	e[++cnt]=(edge){y,head[x]};
	head[x]=cnt;
	return;
}
struct Seg_T
{
	int rt[MAXN],lc[MAXN*100],rc[MAXN*100],sumv[MAXN*100],maxv[MAXN*100],cnt;
	inline void push_up(int o)
	{
		sumv[o]=sumv[lc[o]]+sumv[rc[o]];
		maxv[o]=max(maxv[lc[o]],maxv[rc[o]]);
		return;
	}
	void update(int &o,int l,int r,int x,int k)
	{
		if(!o)o=++cnt;
		if(l==r)
		{
			maxv[o]=sumv[o]=k;
			return;
		}
		int mid=(l+r)>>1;
		if(x<=mid)update(lc[o],l,mid,x,k);
		else update(rc[o],mid+1,r,x,k);
		push_up(o);
		return;
	}
	int query_max(int o,int l,int r,int yl,int yr)
	{
		if(!o)return 0;
		if(yl<=l&&r<=yr)return maxv[o];
		int mid=(l+r)>>1,ret=0;
		if(yl<=mid)ret=query_max(lc[o],l,mid,yl,yr);
		if(yr>mid)ret=max(ret,query_max(rc[o],mid+1,r,yl,yr));
		return ret;
	}
	int query_sum(int o,int l,int r,int yl,int yr)
	{
		if(!o)return 0;
		if(yl<=l&&r<=yr)return sumv[o];
		int mid=(l+r)>>1,ret=0;
		if(yl<=mid)ret=query_sum(lc[o],l,mid,yl,yr);
		if(yr>mid)ret+=query_sum(rc[o],mid+1,r,yl,yr);
		return ret;
	}
}T1;
struct Tree_D
{
	int son[MAXN],fa[MAXN],sum[MAXN],top[MAXN],pre[MAXN],depth[MAXN],cnt;
	void dfs1(int u,int lst,int dep)
	{
		fa[u]=lst;
		sum[u]=1;
		depth[u]=dep;
		int t=0;
		for(int i=head[u];i;i=e[i].next)
		{
			int v=e[i].v;
			if(v==lst)continue;
			dfs1(v,u,dep+1);
			sum[u]+=sum[v];
			if(sum[v]>t)
			{
				t=sum[v];
				son[u]=v;
			}
		}
		return;
	}
	void dfs2(int u,int lst)
	{
		top[u]=lst;
		pre[u]=++cnt;
		sub[cnt]=u;
		if(son[u])dfs2(son[u],lst);
		for(int i=head[u];i;i=e[i].next)
		{
			int v=e[i].v;
			if(v==fa[u]||v==son[u])continue;
			dfs2(v,v);
		}
		return;
	}
	int query(int u,int v,int k,bool flag)
	{
		int ret=0;
		while(true)
		{
			int f1=top[u],f2=top[v]; 
			if(f1==f2)
			{
				int k1=min(pre[u],pre[v]),k2=max(pre[u],pre[v]);
				if(!flag)ret=max(ret,T1.query_max(T1.rt[k],1,n,k1,k2));
				else ret+=T1.query_sum(T1.rt[k],1,n,k1,k2);
				break;
			}
			if(depth[f1]<depth[f2])
			{
				if(!flag)ret=max(ret,T1.query_max(T1.rt[k],1,n,pre[f2],pre[v]));
				else ret+=T1.query_sum(T1.rt[k],1,n,pre[f2],pre[v]);
				v=fa[f2];
			}
			else
			{
				if(!flag)ret=max(ret,T1.query_max(T1.rt[k],1,n,pre[f1],pre[u]));
				else ret+=T1.query_sum(T1.rt[k],1,n,pre[f1],pre[u]);
				u=fa[f1];
			}
		}
		return ret;
	}
}T2;
int main()
{
#ifndef ONLINE_JUDGE
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
#endif
	n=read();m=read();
	for(int i=1;i<=n;++i)a[i]=read(),b[i]=read();
	for(int i=1;i<n;++i)
	{
		int x=read(),y=read();
		addedge(x,y);addedge(y,x);
	}
	T2.dfs1(1,0,1);
	T2.dfs2(1,1);
	for(int i=1;i<=n;++i)T1.update(T1.rt[b[i]],1,n,T2.pre[i],a[i]);
	while(m--)
	{
		char op[4];
		scanf("%s",op);
		if(op[0]=='C')
		{
			if(op[1]=='C')
			{
				int x=read(),y=read();
				T1.update(T1.rt[b[x]],1,n,T2.pre[x],0);
				T1.update(T1.rt[y],1,n,T2.pre[x],a[x]);
				b[x]=y;
			}
			else
			{
				int x=read(),y=read();
				T1.update(T1.rt[b[x]],1,n,T2.pre[x],a[x]=y);
			}
		}
		else
		{
			int x=read(),y=read();
			printf("%d\n",T2.query(x,y,b[x],op[1]=='S'));
		}
	}
	return 0;
}
